Išmokite sukurti saugią kriptovaliutų piniginę nuo nulio naudojant Python. Šis išsamus vadovas apima pagrindines sąvokas, kriptografiją, bibliotekas ir praktinius kodo pavyzdžius.
Kriptovaliutų piniginės kūrimas su Python: išsamus vadovas
Sparčiai besikeičiančiame skaitmeninių finansų pasaulyje kriptovaliutos tapo transformuojančia jėga. Šios revoliucijos centre yra piniginės koncepcija – jūsų asmeniniai vartai į sąveiką su „blockchain“ tinklais. Nors egzistuoja daug komercinių piniginių, supratimas, kaip jos veikia iš vidaus, yra neįkainojamas įgūdis bet kuriam programuotojui ar technologijų entuziastui. Šis vadovas demistifikuos procesą, vesdamas jus per funkcinės kriptovaliutų piniginės kūrimą nuo nulio naudojant Python.
Apžvelgsime pagrindinius kriptografijos principus, svarbiausias Python bibliotekas ir žingsnis po žingsnio diegimą, skirtą raktų generavimui, adresų kūrimui Bitcoin ir Ethereum tinklams bei transakcijų pasirašymui. Perskaitę šį straipsnį, jūs gerai suprasite piniginės mechaniką ir turėsite savo veikiančią komandinės eilutės piniginę.
Atsakomybės apribojimas: Šiame vadove pateiktas kodas ir koncepcijos yra skirtos tik edukaciniams tikslams. Gamybai paruoštos piniginės kūrimas reikalauja griežtų saugumo auditų, išsamių bandymų ir pažangių saugumo priemonių. Nenaudokite čia sukurtos piniginės tikroms lėšoms saugoti.
Kriptovaliutų piniginės pagrindinių koncepcijų supratimas
Prieš parašydami bent vieną kodo eilutę, svarbu suvokti, kas iš tiesų yra kriptovaliutų piniginė. Priešingai nei pavadinimas, piniginė „nesaugo“ jūsų monetų. Jūsų kriptovaliuta egzistuoja kaip įrašai paskirstytoje knygoje – „blockchain“. Piniginė yra programinė įranga, valdanti kriptografinius raktus, kurie suteikia jums nuosavybės teisę ir kontrolę į jūsų turtą toje knygoje.
Pagrindiniai bet kurios nekustodijinės piniginės komponentai yra:
1. Privatūs raktai: jūsų skaitmeninė paslaptis
Privatus raktas yra pati svarbiausia informacija jūsų piniginėje. Tai labai didelis, atsitiktinai sugeneruotas skaičius, laikomas paslaptyje ir žinomas tik jums. Jo paskirtis – sukurti skaitmeninį parašą, kuris tarnauja kaip nepaneigiamas įrodymas, kad jūs patvirtinote transakciją. Jei prarasite savo privatų raktą, prarasite prieigą prie savo lėšų amžinai. Jei kas nors kitas prie jo prieis, jis turės visišką jūsų lėšų kontrolę.
- Analogija: Įsivaizduokite privatų raktą kaip pagrindinį raktą nuo jūsų skaitmeninio seifo. Jis gali atidaryti seifą ir patvirtinti jo turinio judėjimą.
2. Viešieji raktai: jūsų bendrinamas identifikatorius
Viešasis raktas yra matematiškai išvedamas iš jūsų privataus rakto, naudojant vienakryptę kriptografinę funkciją, žinomą kaip elipsinių kreivių kriptografija (ECC). Nors iš privataus rakto galima sugeneruoti viešąjį, atvirkštinis veiksmas yra skaičiavimo požiūriu neįmanomas. Šis vienakryptis ryšys yra kriptovaliutų saugumo pagrindas.
- Analogija: Viešasis raktas yra tarsi jūsų banko sąskaitos numeris. Galite juo dalintis su kitais, kad jie galėtų jums siųsti pinigus, bet tai nesuteikia jiems galimybės išimti lėšų.
3. Adresai: jūsų viešoji paskirties vieta
Piniginės adresas yra trumpesnis, patogesnis vartotojui jūsų viešojo rakto atvaizdas. Jis generuojamas pritaikius viešajam raktui papildomus maišos algoritmus (pvz., SHA-256 ir RIPEMD-160) ir dažnai apima kontrolinę sumą, kad būtų išvengta rašybos klaidų siunčiant lėšas. Tai simbolių eilutė, kuria dalinatės su kitais, norėdami gauti kriptovaliutą.
- Analogija: Jei viešasis raktas yra jūsų sąskaitos numeris, tai adresas yra tarsi specifinis, suformatuotas sąskaitos faktūros numeris, turintis klaidų tikrinimo funkcijas.
4. Kriptografinis ryšys: vienos krypties gatvė
Ryšys tarp šių komponentų yra griežta, vienos krypties hierarchija:
Privatus raktas → Viešasis raktas → Adresas
Ši struktūra užtikrina, kad galite saugiai dalintis savo adresu, tiesiogiai neatskleisdami savo viešojo rakto (kai kuriais atvejais) ir, žinoma, niekada neatskleisdami savo privataus rakto.
5. Skaitmeniniai parašai: nuosavybės įrodymas
Kai norite siųsti kriptovaliutą, sukuriate transakcijos pranešimą (pvz., „Siųsti 0,5 BTC iš adreso A į adresą B“). Jūsų piniginės programinė įranga tada naudoja jūsų privatų raktą, kad sukurtų unikalų skaitmeninį parašą šiai konkrečiai transakcijai. Šis parašas kartu su transakcija yra transliuojamas į tinklą. „Maineriai“ ir mazgai tinkle gali naudoti jūsų viešąjį raktą, kad patikrintų, ar parašas yra galiojantis, taip patvirtindami, kad transakciją patvirtino teisėtas lėšų savininkas, niekada nematydami jūsų privataus rakto.
Python programavimo aplinkos paruošimas
Norėdami sukurti mūsų piniginę, mums reikės kelių specializuotų Python bibliotekų, kurios tvarko sudėtingą kriptografiją. Įsitikinkite, kad esate įdiegę Python 3.6 ar naujesnę versiją. Būtinas bibliotekas galite įdiegti naudodami pip:
pip install ecdsa pysha3 base58
Panagrinėkime, ką daro kiekviena biblioteka:
- ecdsa: Tai esminė biblioteka, skirta Elipsinių kreivių skaitmeninio parašo algoritmo (ECDSA) diegimui. Ją naudosime privačių ir viešųjų raktų generavimui pagal
SECP256k1kreivę, kuri yra standartas, naudojamas Bitcoin, Ethereum ir daugelyje kitų kriptovaliutų. Ji taip pat tvarko skaitmeninių parašų kūrimą ir tikrinimą. - pysha3: Nors Python integruota
hashlibbiblioteka palaiko daugybę maišos algoritmų, joje nėra Keccak-256, kuris reikalingas Ethereum adresų generavimui. Ši biblioteka suteikia šią funkciją. - base58: Ši biblioteka įgyvendina Base58Check kodavimą – formatą, naudojamą sukurti žmonėms skaitomus Bitcoin adresus. Ji apima kontrolinę sumą, padedančią išvengti klaidų dėl netikslaus teksto įvedimo.
- hashlib: Ši integruota Python biblioteka bus naudojama SHA-256 ir RIPEMD-160 maišai, kurie yra esminiai žingsniai kuriant Bitcoin adresą.
Žingsnis po žingsnio diegimas: piniginės logikos kūrimas
Dabar pereikime prie kodo. Kursime pagrindines mūsų piniginės funkcijas dalimis, paaiškindami kiekvieną žingsnį.
1 žingsnis: privataus rakto generavimas
Privatus raktas iš esmės yra 256 bitų (32 baitų) skaičius. Svarbiausias reikalavimas yra tai, kad jis turi būti generuojamas naudojant tikrą atsitiktinumą. Naudojant silpną atsitiktinių skaičių generatorių, raktai gali būti nuspėjami, ir puolėjas galėtų juos atspėti.
Python integruotas secrets modulis yra skirtas kriptografiškai saugių atsitiktinių skaičių generavimui, todėl jis puikiai tinka mūsų poreikiams.
Čia `os.urandom(32)` pateikia 32 kriptografiškai saugius atsitiktinius baitus, būtent tai, ko mums reikia 256 bitų privačiam raktui.
2 žingsnis: viešojo rakto išvedimas
Toliau iš privataus rakto išvesime viešąjį raktą, naudodami SECP256k1 elipsinę kreivę. `ecdsa` biblioteka šį procesą padaro paprastą.
`ecdsa.SigningKey` objektas atspindi mūsų privatų raktą. Tada gauname atitinkamą `verifying_key` (viešąjį raktą) ir eksportuojame jį „nesuspaustu“ formatu. Nesuspaustas viešasis raktas yra 65 baitų ilgio: `0x04` priešdėlis, po kurio eina 32 baitų X koordinatė ir 32 baitų Y koordinatė taško elipsinėje kreivėje.
3 žingsnis: Bitcoin adreso kūrimas
Bitcoin adreso generavimas iš viešojo rakto yra kelių etapų procesas, skirtas saugumui ir klaidų tikrinimui. Štai standartinė P2PKH (Pay-to-Public-Key-Hash) adreso generavimo eiga:
- SHA-256 maiša: Atlikti viešojo rakto maišą naudojant SHA-256.
- RIPEMD-160 maiša: Atlikti ankstesnio žingsnio rezultato maišą naudojant RIPEMD-160.
- Pridėti versijos baitą: Prie RIPEMD-160 maišos pridėti versijos baito priešdėlį. Bitcoin pagrindiniam tinklui (mainnet) tai yra `0x00`.
- Kontrolinės sumos skaičiavimas: Du kartus atlikti SHA-256 maišą išplėstinei maišai ir paimti pirmuosius 4 galutinės maišos baitus. Tai yra kontrolinė suma.
- Pridėti kontrolinę sumą: Prie versijos priešdėliu papildytos maišos galo pridėti 4 baitų kontrolinę sumą.
- Base58Check kodavimas: Užkoduoti visą baitų eilutę naudojant Base58Check, kad gautumėte galutinį, žmogui skaitomą adresą.
Įgyvendinkime tai Python kalba:
```python def public_key_to_btc_address(public_key_bytes): """Konvertuoti viešąjį raktą į Bitcoin P2PKH adresą.""" # 1 ir 2 žingsniai: SHA-256, tada RIPEMD-160 sha256_hash = hashlib.sha256(public_key_bytes).digest() ripemd160_hash = hashlib.new('ripemd160') ripemd160_hash.update(sha256_hash) hashed_public_key = ripemd160_hash.digest() # 3 žingsnis: pridėti versijos baitą (0x00 Mainnet tinklui) version_byte = b'\x00' versioned_hash = version_byte + hashed_public_key # 4 ir 5 žingsniai: sukurti kontrolinę sumą ir pridėti # Dviguba SHA-256 maiša checksum_hash_1 = hashlib.sha256(versioned_hash).digest() checksum_hash_2 = hashlib.sha256(checksum_hash_1).digest() checksum = checksum_hash_2[:4] binary_address = versioned_hash + checksum # 6 žingsnis: Base58Check kodavimas btc_address = base58.b58encode(binary_address).decode('utf-8') return btc_address ```4 žingsnis: Ethereum adreso kūrimas
Ethereum adreso generavimas yra paprastesnis, palyginti su Bitcoin. Jis apima Keccak-256 maišos apskaičiavimą iš viešojo rakto ir paskutinių 20 rezultato baitų naudojimą.
- Keccak-256 maiša: Apskaičiuoti viešojo rakto Keccak-256 maišą. Atkreipkite dėmesį, kad turime naudoti viešąjį raktą *be* `0x04` priešdėlio.
- Paimti paskutinius 20 baitų: Ethereum adresas yra paskutiniai 20 baitų (40 šešioliktainių simbolių) šios maišos.
- Formatuoti: Standartiškai adresas pradedamas `0x` priešdėliu.
Įgyvendinkime tai naudojant `pysha3`:
```python def public_key_to_eth_address(public_key_bytes): """Konvertuoti viešąjį raktą į Ethereum adresą.""" # Ethereum adreso generavimas naudoja nesuspaustą viešąjį raktą be 0x04 priešdėlio uncompressed_pk = public_key_bytes[1:] # 1 žingsnis: Keccak-256 maiša keccak_hash = keccak_256(uncompressed_pk).digest() # 2 žingsnis: paimti paskutinius 20 baitų eth_address_bytes = keccak_hash[-20:] # 3 žingsnis: formatuoti su '0x' priešdėliu eth_address = '0x' + eth_address_bytes.hex() return eth_address ```5 žingsnis: pranešimo pasirašymas
Skaitmeninis parašas įrodo, kad privataus rakto savininkas patvirtino pranešimą (pvz., transakciją). Procesas apima pranešimo maišos, o ne pačio neapdoroto pranešimo pasirašymą, siekiant efektyvumo ir saugumo.
```python def sign_message(private_key_bytes, message): """Pasirašyti pranešimą su nurodytu privačiu raktu.""" # Standartinė praktika yra pasirašyti pranešimo maišą message_hash = hashlib.sha256(message.encode('utf-8')).digest() sk = ecdsa.SigningKey.from_string(private_key_bytes, curve=ecdsa.SECP256k1) signature = sk.sign(message_hash) return signature ```6 žingsnis: parašo tikrinimas
Tikrinimas yra atvirkštinis procesas. Bet kas, turintis viešąjį raktą, originalų pranešimą ir parašą, gali patvirtinti, kad parašas yra autentiškas. Taip „blockchain“ tinklas patvirtina transakcijas.
```python def verify_signature(public_key_bytes, signature, message): """Patikrinti pranešimo parašą su nurodytu viešuoju raktu.""" message_hash = hashlib.sha256(message.encode('utf-8')).digest() vk = ecdsa.VerifyingKey.from_string(public_key_bytes, curve=ecdsa.SECP256k1, hashfunc=hashlib.sha256) try: # `verify` metodas grąžins True, jei galiojantis, arba sukels išimtį return vk.verify(signature, message_hash) except ecdsa.BadSignatureError: return False ```Piniginės surinkimas: paprasta komandinės eilutės sąsaja (CLI)
Dabar, kai turime visas pagrindines funkcijas, sujunkime jas į paprastą, naudojamą komandinės eilutės įrankį. Sukursime `Wallet` klasę, kad inkapsuliuotume logiką, ir naudosime Python `argparse` modulį vartotojo komandoms apdoroti.
Štai pilnas scenarijus, kuris integruoja visas mūsų funkcijas į vientisą programą.
```python #!/usr/bin/env python3 import os import hashlib import base58 import ecdsa import argparse from sha3 import keccak_256 class Wallet: """Atstovauja kriptovaliutų piniginę su raktų valdymu ir adresų generavimu.""" def __init__(self, private_key_hex=None): if private_key_hex: self.private_key = bytes.fromhex(private_key_hex) else: self.private_key = self._generate_private_key() self.public_key = self._private_to_public_key(self.private_key) self.btc_address = self._public_to_btc_address(self.public_key) self.eth_address = self._public_to_eth_address(self.public_key) def _generate_private_key(self): return os.urandom(32) def _private_to_public_key(self, private_key): sk = ecdsa.SigningKey.from_string(private_key, curve=ecdsa.SECP256k1) return sk.verifying_key.to_string("uncompressed") def _public_to_btc_address(self, public_key): sha256_hash = hashlib.sha256(public_key).digest() ripemd160 = hashlib.new('ripemd160') ripemd160.update(sha256_hash) hashed_pk = ripemd160.digest() versioned_hash = b'\x00' + hashed_pk checksum = hashlib.sha256(hashlib.sha256(versioned_hash).digest()).digest()[:4] binary_address = versioned_hash + checksum return base58.b58encode(binary_address).decode('utf-8') def _public_to_eth_address(self, public_key): uncompressed_pk = public_key[1:] keccak_hash = keccak_256(uncompressed_pk).digest() return '0x' + keccak_hash[-20:].hex() def display_details(self): print(f"Privatus raktas (hex): {self.private_key.hex()}") print(f"Viešasis raktas (hex): {self.public_key.hex()}") print(f"Bitcoin adresas: {self.btc_address}") print(f"Ethereum adresas: {self.eth_address}") def main(): parser = argparse.ArgumentParser(description="Paprasta komandinės eilutės kriptovaliutų piniginė.") parser.add_argument("command", choices=["create", "details"], help="Komanda, kurią reikia įvykdyti.") parser.add_argument("--privatekey", help="Esamas privatus raktas šešioliktainiu formatu, iš kurio gauti detales.") args = parser.parse_args() if args.command == "create": wallet = Wallet() print("--- Sukurta nauja piniginė ---") wallet.display_details() print("\n*** SVARBU ***") print("Išsaugokite savo privatų raktą saugioje vietoje. Tai vienintelis būdas pasiekti savo lėšas.") elif args.command == "details": if not args.privatekey: print("Klaida: 'details' komandai reikalingas privatus raktas, nurodytas su --privatekey vėliavėle.") return try: wallet = Wallet(private_key_hex=args.privatekey) print("--- Piniginės detalės ---") wallet.display_details() except Exception as e: print(f"Klaida įkeliant piniginę iš privataus rakto: {e}") if __name__ == "__main__": main() ```Kaip naudoti šį CLI įrankį:
- Išsaugokite aukščiau pateiktą kodą kaip Python failą (pvz., `cli_wallet.py`).
- Atidarykite savo terminalą arba komandinę eilutę.
- Norėdami sukurti naują piniginę: `python cli_wallet.py create`
- Norėdami peržiūrėti detales iš esamo privataus rakto: `python cli_wallet.py details --privatekey JŪSŲ_PRIVATUS_RAKTAS_HEX_FORMATU`
Saugumo gerosios praktikos ir svarbūs aspektai
Sėkmingai sukūrėme pagrindinę piniginę, tačiau gamybai paruošta programa reikalauja daug gilesnio dėmesio saugumui. Štai keletas svarbių punktų, į kuriuos reikia atsižvelgti.
1. Niekada nesaugokite privačių raktų atviru tekstu
Mūsų scenarijus išveda privatų raktą į konsolę, o tai yra labai nesaugu. Tikroje programoje privatūs raktai turėtų būti užšifruoti saugojimo metu, naudojant stiprų slaptažodį. Jie turėtų būti iššifruojami atmintyje tik tada, kai reikalingi pasirašymui. Profesionalūs sprendimai dažnai naudoja aparatinės įrangos saugumo modulius (HSM) arba saugius anklavus įrenginiuose raktams apsaugoti.
2. Entropijos svarba
Jūsų piniginės saugumas prasideda nuo atsitiktinumo (entropijos), naudojamo generuojant privatų raktą. `os.urandom` yra geras šaltinis daugelyje modernių operacinių sistemų, tačiau didelės vertės programoms programuotojai dažnai renka entropiją iš kelių šaltinių, kad užtikrintų nenuspėjamumą.
3. Mnemoninės frazės (angl. seed phrases) – pramonės standartas
Rankiniu būdu daryti ilgų šešioliktainių privačių raktų atsargines kopijas yra sudėtinga ir kupina klaidų. Pramonė išsprendė šią problemą su hierarchinėmis deterministinėmis (HD) piniginėmis (apibrėžtomis BIP-32) ir mnemoninėmis frazėmis (BIP-39). Mnemoninė frazė yra 12–24 įprastų žodžių seka, kurią galima naudoti deterministiškai atkurti jūsų pagrindinį privatų raktą ir visus vėlesnius raktus. Tai padaro piniginės atsarginių kopijų kūrimą ir atkūrimą daug patogesnį vartotojui.
4. Tai edukacinis įrankis, o ne gamybai skirta piniginė
Būtina pabrėžti, kad šis diegimas yra supaprastintas modelis. Realaus pasaulio piniginė turi valdyti kelis adresus, sąveikauti su „blockchain“ mazgais, kad gautų balansus ir sudarytų transakcijas, apskaičiuotų mokesčius ir transliuotų pasirašytas transakcijas į tinklą. Jai taip pat reikalinga saugi vartotojo sąsaja ir patikimas klaidų tvarkymas.
5. Sąveika su tinklu
Mūsų piniginė gali generuoti raktus ir pasirašyti pranešimus, bet ji negali bendrauti su „blockchain“ tinklu. Norėdami sukurti pilnavertę programą, jums reikėtų integruoti bibliotekas, kurios gali prisijungti prie „blockchain“ mazgų per RPC (nuotolinis procedūrų iškvietimas). Ethereum tinklui `web3.py` yra standartinė biblioteka. Bitcoin tinklui galima naudoti bibliotekas, tokias kaip `python-bitcoinlib`.
Išvados ir tolesni žingsniai
Sveikiname! Jūs sėkmingai sukūrėte kriptovaliutų piniginės kriptografinį branduolį naudodami Python. Keliavome nuo pagrindinės viešojo/privataus rakto kriptografijos teorijos iki praktinio įgyvendinimo, kuris generuoja galiojančius adresus tiek Bitcoin, tiek Ethereum tinklams.
Šis projektas suteikia tvirtą pagrindą gilesniam „blockchain“ technologijos tyrinėjimui. Jūs patys įsitikinote, kad piniginė iš esmės yra sudėtinga raktų valdymo sistema, pagrįsta patikrintais kriptografiniais principais.
Kokie tolimesni žingsniai? Apsvarstykite šiuos iššūkius:
- Įdiegti HD pinigines: Išnagrinėkite BIP-32, BIP-39 ir BIP-44 standartus, kad sukurtumėte piniginę, galinčią valdyti milijonus adresų iš vienos mnemoninės frazės (seed phrase).
- Prisijungti prie tinklo: Naudokite `web3.py`, kad prisijungtumėte prie Ethereum mazgo (pvz., Infura ar Alchemy), patikrintumėte adreso balansą ir sukonstruotumėte neapdorotą transakciją.
- Sukurti vartotojo sąsają: Sukurkite paprastą grafinę vartotojo sąsają (GUI) naudojant karkasą, pvz., Tkinter, arba internetinę sąsają naudojant Flask/Django, kad jūsų piniginė būtų patogesnė vartotojui.
- Tyrinėti kitus „blockchain“ tinklus: Ištirkite, kaip kitos „blockchain“ platformos generuoja savo adresus, ir pritaikykite savo kodą, kad jas palaikytumėte.
„Blockchain“ pasaulis yra pagrįstas atvirojo kodo bendradarbiavimu ir žinių troškimu. Kurdami tokius įrankius, jūs ne tik mokotės programuoti – jūs mokotės naujos skaitmeninės ekonomikos kalbos. Toliau eksperimentuokite, kurkite ir tyrinėkite didžiulį decentralizuotų technologijų potencialą.